package com.hwl.eduservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hwl.commonutils.utils.AssertUtil;
import com.hwl.eduservice.feign.OssFileService;
import com.hwl.eduservice.feign.VodMediaService;
import com.hwl.eduservice.mapper.*;
import com.hwl.eduservice.pojo.*;
import com.hwl.eduservice.pojo.frontVo.WebCourseQueryVo;
import com.hwl.eduservice.pojo.frontVo.WebCourseVo;
import com.hwl.eduservice.pojo.vo.CourseInfoForm;
import com.hwl.eduservice.pojo.vo.CoursePublishVo;
import com.hwl.eduservice.pojo.vo.CourseQueryVo;
import com.hwl.eduservice.pojo.vo.CourseVo;
import com.hwl.eduservice.service.CourseService;
import com.hwl.servicebase.dto.CourseDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程 服务实现类
 * </p>
 *
 * @author long
 * @since 2021-09-21
 */
@Slf4j
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {

    @Resource
    private CourseDescriptionMapper descriptionMapper;
    @Resource
    private OssFileService ossFileService;
    @Resource
    private VideoMapper videoMapper;
    @Resource
    private ChapterMapper chapterMapper;
    @Resource
    private CommentMapper commentMapper;
    @Resource
    private CourseCollectMapper courseCollectMapper;
    @Resource
    private VodMediaService vodMediaService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String addCourseInfo(CourseInfoForm courseInfoForm) {
        //课程信息
        Course course = new Course();
        BeanUtils.copyProperties(courseInfoForm, course);
        course.setStatus(Course.COURSE_DRAFT);
        AssertUtil.isTrue(baseMapper.insert(course) <= 0, "添加课程信息时失败！");

        //课程描述
        CourseDescription courseDescription = new CourseDescription()
                .setDescription(courseInfoForm.getDescription()).setId(course.getId());
        AssertUtil.isTrue(descriptionMapper.insert(courseDescription) <= 0, "添加课程描述时失败！");

        return course.getId();
    }

    @Override
    public CourseInfoForm getCourseInfo(String courseId) {
        Course course = baseMapper.selectById(courseId);
        CourseInfoForm courseInfoForm = new CourseInfoForm();
        BeanUtils.copyProperties(course, courseInfoForm);

        CourseDescription courseDescription = descriptionMapper.selectById(courseId);
        courseInfoForm.setDescription(courseDescription.getDescription());
        return courseInfoForm;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateCourseInfo(CourseInfoForm courseInfoForm) {
        Course course = new Course();
        BeanUtils.copyProperties(courseInfoForm, course);
        if (baseMapper.updateById(course) < 0) {
            return false;
        }

        CourseDescription courseDescription = new CourseDescription()
                .setDescription(courseInfoForm.getDescription()).setId(courseInfoForm.getId());
        return descriptionMapper.updateById(courseDescription) >= 0;
    }

    @Override
    public IPage<CourseVo> selectPage(Long page, Long limit, CourseQueryVo courseQueryVo) {
        return baseMapper.getAllCourseInfo(new Page<>(page, limit), courseQueryVo);
    }

    @Override
    public boolean removeCoverById(String id) {
        Course course = baseMapper.selectById(id);
        if (course != null && !StringUtils.isEmpty(course.getCover())) {
            Boolean flag = ossFileService.removeFile(course.getCover()).getSuccess();
            log.info(flag ? "远程调用删除课程封面成功！" : "远程调用删除课程封面失败！");
            return flag;
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeCourseById(String id) {
        QueryWrapper<Video> videoQueryWrapper = new QueryWrapper<Video>().eq("course_id", id);

        List<String> vodIds = videoMapper.selectList(videoQueryWrapper)
                .stream().filter(video -> !StringUtils.isEmpty(video.getVideoSourceId()))
                .map(Video::getVideoSourceId)
                .collect(Collectors.toList());
        //删除该课程下所有的课时视频
        if (vodIds.size() > 0) {
            Boolean flag = vodMediaService.deleteBatchVideo(vodIds).getSuccess();
            log.info(flag ? "远程调用批量删除课时视频成功！" : "远程调用批量删除课时视频失败！");
        }

        //删除课时
        AssertUtil.isTrue(videoMapper.delete(videoQueryWrapper) < 0, "删除课程小节时失败！");

        //删除课程章节
        QueryWrapper<Chapter> chapterQueryWrapper = new QueryWrapper<Chapter>().eq("course_id", id);
        AssertUtil.isTrue(chapterMapper.delete(chapterQueryWrapper) < 0, "删除课程章节时失败！");

        //删除课程描述
        AssertUtil.isTrue(descriptionMapper.deleteById(id) < 0, "删除课程描述时失败！");

        //删除课程评论
        QueryWrapper<Comment> commentQueryWrapper = new QueryWrapper<Comment>().eq("course_id", id);
        log.debug(commentMapper.delete(commentQueryWrapper) < 0 ? "删除课程评论失败！" : "删除课程评论成功！");

        //删除课程收藏
        QueryWrapper<CourseCollect> collectQueryWrapper = new QueryWrapper<CourseCollect>().eq("course_id", id);
        log.debug(courseCollectMapper.delete(collectQueryWrapper) < 0 ? "删除课程收藏失败！" : "删除课程收藏成功！");

        //删除课程基本信息
        return this.removeById(id);
    }

    @Override
    public CoursePublishVo getCoursePublishVoById(String id) {
        return baseMapper.selectCoursePublish(id);
    }

    @Override
    public List<Course> webSelectList(WebCourseQueryVo webCourseQueryVo) {
        QueryWrapper<Course> wrapper = new QueryWrapper<>();
        wrapper.eq("status", Course.COURSE_NORMAL); //已发布的课程

        if (!StringUtils.isEmpty(webCourseQueryVo.getSubjectParentId())) {
            wrapper.eq("subject_parent_id", webCourseQueryVo.getSubjectParentId());
        }

        if (!StringUtils.isEmpty(webCourseQueryVo.getSubjectId())) {
            wrapper.eq("subject_id", webCourseQueryVo.getSubjectId());
        }

        if (!StringUtils.isEmpty(webCourseQueryVo.getBuyCountSort())) {
            wrapper.orderByDesc("buy_count");
        }

        if (!StringUtils.isEmpty(webCourseQueryVo.getGmtCreateSort())) {
            wrapper.orderByDesc("gmt_create");
        }

        if (!StringUtils.isEmpty(webCourseQueryVo.getPriceSort())) {
            if (webCourseQueryVo.getType() == null || webCourseQueryVo.getType() == 1) {
                wrapper.orderByAsc("price");
            } else {
                wrapper.orderByDesc("price");
            }
        }

        return baseMapper.selectList(wrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public WebCourseVo selectCourseById(String courseId) {
        Course course = baseMapper.selectById(courseId);
        course.setViewCount(course.getViewCount() + 1);
        log.debug(baseMapper.updateById(course) > 0 ? "课程浏览量+1！" : "课程浏览量更新失败！");

        //获取课程信息
        return baseMapper.selectCourseById(courseId);
    }

    @Override
    public CourseDto getCourseDtoById(String courseId) {
        return baseMapper.getCourseDtoById(courseId);
    }

    @Override
    public void updateBuyCountById(String id) {
        Course course = baseMapper.selectById(id);
        course.setBuyCount(course.getBuyCount() + 1);
        log.debug(baseMapper.updateById(course) > 0 ? "更新课程销量成功！" : "更新课程销量失败！");
    }
}
